<?php


/**
 * @brief Klasa kontrolera commodities
 *
 * Klasa udostepnia interfej CRUD towarow.
 *Oprcz tego zawarto tu akcje usuwania i doawania
 * towarow do wiazek.
 *
 */
class CommoditiesController extends Zend_Controller_Action
{

    /**
     * @brief Metoda inicjujaca
     * 
     * Odpowiedzialan za szeg czynnosci:
     * - Odczyt informacji z flash messnegera
     * - Inicjacje maperow
     * - Odczyt statusu zalogowania
     * - Inicjacje kontekstu ajaxowego niektorych akcji
     */
    public function init()
    {
        $this->request = $this->getRequest();
        $this->view->render('utility/_headbox.phtml');
        
        $this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
        $this->view->messages = $this->_flashMessenger->getMessages();

        
        $auth = Zend_Auth::getInstance();
        if($auth->hasIdentity()){
            $this->_user = $auth->getIdentity();
        }
        
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('show', 'html')
                    ->addActionContext('add', 'html')
                ->initContext();
    }

    /**
     * @brief Akcja index
     * 
     * Na ekranie powziazanym z ta metoda wyswietlane sa wszystkie zdefiniowane
     * i nie usuniete towary uzytkownika. Na dole strony jest folmularz inicjujacy 
     * tworzenie nowego towaru.
     * 
     */    
    public function indexAction()
    {
        $this->actionIsProtected();
        $query = ('MarketEntity_id = "'.$this->_user->login.'" and used = 0');
        //$query = ('MarketEntity_id = "'.$this->_user->login.'"');
        $this->view->form = new Application_Form_CatSelect();
        $mapper = new Application_Model_CommodityMapper();
        $this->view->commodities = $mapper->fetchAll($query);

    }


    /**
     * @brief Akcja new
     * 
     * Na ekranie tej akcji odbywa się tworzenie nowego towaru.
     * Akcja tez tworzy go jak otrzyma zadanie POST z parametrami towaru.
     * 
     */  
    public function newAction()
    {
        $affMapper = new Application_Model_NodeAffiliationMapper();
        $check = $affMapper->fetchNodes($this->_user->login);
        if(empty($check)){
            $this->_helper->flashMessenger->addMessage('error/Wybierz lokalizacje!');
            $this->_helper->redirector('nodes', 'mymca');
        }
        
        $cat = $this->getRequest()->getParam('cat');
        if(!isset ($cat)){
            $this->_helper->flashMessenger->addMessage('error/Nie wybrano kategorii!');
            $this->_helper->redirector('index','commodities');
        }
        $form = new Application_Form_AddCommodity(array('cat'=>$cat,'user'=>$this->_user->login));
        $this->view->form = $form;
        $request = $this->getRequest();
        $mapper = new Application_Model_CommodityMapper();
        $ok = TRUE;
        
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                $values = $form->getValues();
                $commodity = new Application_Model_Commodity($values);
                if($values['period']!= 0){
                    if(!empty($values['from']) && !empty($values['to'])){
                        
                        $this->view->messages[] = 'error/Nie można wprowadzić dwóch okresów dostaw!';
                        echo 'asaasasas4';
                        $ok = FALSE;
                    } else {
                        $commodity->setHasDeliveryTime(1);
                        $commodity->setCalendarPeriod_id($values['period']);
                    }   
                } else {
                    if(isset($values['from']) && isset($values['to'])){
                        $commodity->setStartTime($this->DBdate($values['from']));
                        $commodity->setEndTime($this->DBdate($values['to']));
                        $commodity->setHasDeliveryTime(0);
                        if(!$this->compareDates($commodity->getStartTime(), $commodity->getEndTime())){
                            $this->view->messages[] = 'error/Wprowadzono błędne daty!';
                            $ok = FALSE;
                        }
                    } else {
                        $this->view->messages[] = 'error/Nie wprowadzono dat!';
                        $ok = FALSE;
                        echo 'asaasasas2';
                    }
                }
                
                $commodity->setUsed(0);
                $commodity->setMarketEntity_id($this->_user->login);
                $location = explode('.', $values['location']);
                
                if($location[0] == 'arc')  
                {
                    $commodity->setNetworkArc_id($location[1]);
                } elseif ($location[0] == 'node') {
                    $commodity->setNetworkNode_id($location[1]);
                }
                
                if($ok){
                    $mapper->save($commodity);
                    $this->_helper->flashMessenger->addMessage('success/Utworzono nowy towar');
                    $this->_helper->redirector('index','commodities');
                }
                
            }
        }
        
    }

    /**
     * @brief Akcja edit
     * 
     * Na ekranie powziazanym z ta metoda przebiego edycja towarow.
     * Naturalnie odbywa sie tu rowniez przetwarzania zadania z 
     * nowymi parametrami towaru.
     */  
    public function editAction()
    {
        $affMapper = new Application_Model_NodeAffiliationMapper();
        $check = $affMapper->fetchNodes($this->_user->login);
        if(empty($check)){
            $this->_helper->flashMessenger->addMessage('error/Wybierz lokalizacje!');
            $this->_helper->redirector('nodes', 'mymca');
        }
        
        $request = $this->getRequest();
        $id = $request->getParam('id');
        
        $commMapper = new Application_Model_CommodityMapper();
        $commodity = $commMapper->find($id);
        $this->view->commodity = $commodity;
        
        $data = array(
            'id' => $commodity->getCommodity_id(),
            'name' => $commodity->getName(),
            'description' => $commodity->getDescription(),
            'type' => $commodity->getCommodityTypeName(),
            'CommodityType_id' => $commodity->getCommodityType_id(),
        );
        
        
        
        $arc = $commodity->getNetworkArc_id();
        $node = $commodity->getNetworkNode_id();
        if(isset($arc)){
            $data['nType']  = 'Połączenie'; 
            $data['nPlace'] = $commodity->getArcName($arc);
            $data['location'] = 'arc.'.$arc;
            
        } else {
            $data['nType']  = 'Lokalizacja';
            $data['nPlace'] = $commodity->getNodeName($node);
            $data['location'] = 'node.'.$node;
        }
        
        $cType = $commodity->getHasDeliveryTime();
        if($cType){
            $period_id =$commodity->getCalendarPeriod_id();
            $periodMapper = new Application_Model_CalendarPeriodMapper();
            $period = $periodMapper->find($period_id);
            $data['startTime'] = $period->getStartTime(); 
            $data['endTime'] = $period->getEndTime();
        } else {
            $data['startTime'] = $commodity->getStartTime();
            $data['endTime'] = $commodity->getEndTime();
        }
        
        $type = $commodity->getCommodityType();
        $data['type'] = $type->getName();
        $data['cat'] = $type->getCategoryName();
        
        $cat = $type->getCategory_id();
        
        $form = new Application_Form_AddCommodity(
                array('cat'=>$cat,'user'=>$this->_user->login));
        
        $form->populate($data);
        $this->view->form = $form;
        
        $cid = $commodity->getCommodity_id();
        unset($commodity);
        
        
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                $values = $form->getValues();
                $commodity = new Application_Model_Commodity($values);
                $commodity->setCommodity_id($cid);
                $ok=TRUE;
                
                if($values['period'] != 0){
                    if(!empty($values['from']) && !empty($values['to'])){
                        $this->view->messages[] = 'error/Nie można wprowadzić dwóch okresów dostaw!';
                        $ok = FALSE;
                    } else {
                        $commodity->setHasDeliveryTime(1);
                        $commodity->setCalendarPeriod_id($values['period']);
                    }   
                } else {
                    if(isset($values['from']) && isset($values['to'])){
                        $commodity->setStartTime($this->DBdate($values['from']));
                        $commodity->setEndTime($this->DBdate($values['to']));
                        $commodity->setHasDeliveryTime(0);
                        if(!$this->compareDates($commodity->getStartTime(), $commodity->getEndTime())){
                            $this->view->messages[] = 'error/Wprowadzono błędne daty!';
                            $ok = FALSE;
                        }
                    } else {
                        $this->view->messages[] = 'error/Nie wprowadzono dat!';
                        $ok = FALSE;
                    }
                }
                
                $commodity->setUsed(0);
                $commodity->setMarketEntity_id($this->_user->login);
                $location = explode('.', $values['location']);
                
                if($location[0] == 'arc')  
                {
                    $commodity->setNetworkArc_id($location[1]);
                } elseif ($location[0] == 'node') {
                    $commodity->setNetworkNode_id($location[1]);
                }
                
                if($ok){
                    $commMapper->save($commodity);
                    $this->_helper->flashMessenger->addMessage('success/Zmieniono szczegóły towaru!');
                    $this->_helper->redirector('index','commodities');
                }
                
            }
        }
    }

    /**
     * @brief Akcja show
     * 
     * Akcja wyswietlania szczegolow towaru. Najczesciej wykorzystywana
     * jest ta za pomoca żądań ajaxowych.
     * 
     */  
    public function showAction()
    {


        $id = $this->request->getParam('id');
        $auction = $this->request->getParam('auction');
        if(empty($auction)) {
            $auction = 0;
        }
        $commMapper = new Application_Model_CommodityMapper();
        $commodity = $commMapper->find($id);
        $this->view->commodity = $commodity;
        $this->view->auction = $auction;
    }

    /**
     * @brief Akcja delete
     * 
     * Akcja usuwania towaru. Nie jesto usuwany nigdy z bazy danych.
     * Zmiast tego zmieniona jest jego flaga widoczności. 
     * 
     */  
    public function deleteAction()
    {
        $id = $this->getRequest()->getParam('id');
        if(empty($id)){
            $this->_helper->flashMessenger->addMessage('error/Nie podano identyfikatora towaru!');
            $this->_helper->redirector('commodities', 'mymca'); 
        }
        
        $mapper = new Application_Model_CommodityMapper();
        $commodity = $mapper->find($id);
        
        if(empty($commodity)  ||
                $commodity->getMarketEntity_id() != $this->_user->login ||
                $commodity->getUsed() == 1 ) {
            throw new Exception ('Nie masz uprawnien');
        }
        
 
        //zmiana flagi widocznosści
        $commodity->setUsed(1);
        $mapper->save($commodity);
        
        
        $this->_helper->flashMessenger->addMessage('success/Usunięto towar!');
        $this->_helper->redirector('index', 'commodities'); 
    }
    
    /**
     * @brief Akcja add
     * 
     * Akcja sluzy wyswietlaniu formularza dodawania towary do oferty.
     * Za poomoca kals mapujacych ustalane jest czy uzytkownik moze tylko 
     * sprzedac lub kupic danyc towar. Jezeli ejst to towar ktory nie
     * pojawil sie na uakcji to obie opcje sa mozliwe.
     * 
     */  
    public function addAction(){
        $request = $this->request;
        $data = Array();
        $type = $request->getParam('type');
        $data['offer'] = 0 + (int) $request->getParam('offer');
        $data['commodity'] = 0 + (int) $request->getParam('commodity');
        
        if(empty($data['offer']) || empty($data['commodity'])) {
           throw new Exception('Niepoprawne argumenty');
        }
        
        $mapper = new Application_Model_CommodityMapper();
        $commodity = $mapper->find($data['commodity']);
        
        $offerMapper = new Application_Model_OfferMapper();
        $offer = $offerMapper->find($data['offer']);
        $auctionId = $offer->getAuction_id();
        
        if($type == 'new') {
            $form = new Application_Form_AddNewCommodityToOffer($data);
        } elseif ($type == 'old') {
            $affilMapper = new Application_Model_CommodityAffiliationMapper();
            $share = $affilMapper->fetchShareFactor($data['commodity'], $auctionId);
            if($commodity->getMarketEntity_id() == $this->_user->login) {
               $data['share'] = $share; 
            } else {
               $data['share'] = -1 * $share; 
            }
            $form = new Application_Form_AddCommodityToOffer($data);
        } else {
            throw new Exception('Niepoprawne argumenty2');
        }
        
        //var_dump($commodity);
        
        $this->view->commodity = $commodity;
        $this->view->form = $form;
    }
    
    
    /**
     * @brief Akcja insert
     * 
     * Akcja sluzy do dodawania nowych towarow do wiązek w ofertach.
     * W tym miejscu odbywa sie tylko przetwarzanie informacji.
     * 
     */  
    public function insertAction()
    {
        $request = $this->request;
        $offerId = $request->getParam('Offer_id');
        $commodityId = $request->getParam('Commodity_id');
        $offerMapper = new Application_Model_OfferMapper();
        $offer = $offerMapper->find($offerId);
        //sprawdź czy to oferta uzytkownika
        //sprawdz czy aukcja jest zamknięta
        if($offer->getMarketEntity_id() != $this->_user->login ||
                !$offer->offerOpen())
            throw new Exception('Nie mozesz zmieniac tej oferty');
        //sprawdz czy towar jest w ofercie - dodatkowe
        $update = false;
        
        $type = $request->getParam('type');

        
        if($request->isPost()){
                //dodaj do oferty
                $component = new Application_Model_OfferComponent();
                $component->setShareFactor($request->getParam('shareFactor'));
                $component->setQuantity($request->getParam('quantity'));
                $component->setOffer_id($offerId);
                $component->setCommodity_id($commodityId);
                $componentMapper = new Application_Model_OfferComponentMapper();
                try {
                $componentMapper->save($component,$update);
                } catch (Exception $exc) {
                     $componentMapper->save($component,true);
                }
                //dodaj do aukcji 
                if($type == 'new') {
                    $data = array(
                        'Auction_id'      =>$offer->getAuction_id(),
                        'Commodity_id'   =>$component->getCommodity_id(),
                        'shareFactor'   =>$component->getShareFactor(),
                    );
                    $affil= new Application_Model_CommodityAffiliationMapper();
                    try {
                        $affil->save($data);
                    } catch (Exception $exc) {
                        //echo $exc->getTraceAsString();
                    }

                    
                }
        } else {
            $this->_helper->flashMessenger
                    ->addMessage('error/Nie udalo sie dodac towaru');
        }
        
        $this->_helper->flashMessenger->addMessage('success/Dodano towar!');
        $this->_helper->redirector('edit', 'offers', 'default', array(
            'id' => $offerId
        ));
    }        
    
    
    /**
     * @brief Akcja remove
     * 
     * Akcja sluzy do dodawania nowych towarow do wiązek w ofertach.
     * W tym miejscu odbywa sie tylko przetwarzanie informacji.
     * 
     */  
    public function removeAction()
    {
        
        $offerId = $this->request->getParam('offer');
        $commodityId = $this->request->getParam('commodity');
        
        $offerMapper = new Application_Model_OfferMapper();
        $offer = $offerMapper->find($offerId);
        
        //sprawdz czy to oferta uzytkownika
        if($offer->getMarketEntity_id() != $this->_user->login ||
                !$offer->offerOpen())
            throw new Exception('Nie mozesz zmieniac tej oferty');
        $auctionId = $offer->getAuction_id();
        
        
        $affilMapper = new Application_Model_CommodityAffiliationMapper();
        $share = $affilMapper->fetchShareFactor($commodityId, $auctionId);
        
        $selling = count($offerMapper
                ->fetchOfferByAuctionAndComponent($auctionId, $commodityId, -1));
        $buying = count($offerMapper
                ->fetchOfferByAuctionAndComponent($auctionId, $commodityId, 1));
        //sprawdz czy mozna usunac
        
        if(($share == -1 && $selling == 1 && $buying > 0) ||
                ($share = 1 && $buying == 1 && $selling > 0)) {
            $this->_helper->flashMessenger->addMessage("error/Nie można usuną towaru!");
            $this->_helper->redirector('edit', 'offers', 'default', array(
                'id' => $offerId
        ));
        }
        
        $compMapper = new Application_Model_OfferComponentMapper();
        $compMapper->delete($offerId, $commodityId);
        
        //usun z listy towarów w aukcji
        if(($selling == 0 && $buying == 1) || ($selling == 1 && $buying == 0)){
            $affilMapper = new Application_Model_CommodityAffiliationMapper();
            $affilMapper->delete($auctionId, $commodityId);
        }

        $this->_helper->flashMessenger->addMessage("success/Usunieto towar $commodityId!");
        $this->_helper->redirector('edit', 'offers', 'default', array(
            'id' => $offerId
        ));
    }
    
    /**
     * @brief Metoda pomocnicza DBdate
     * 
     * Konwertuje string z czasem na format ISO
     * 
     */ 
    private function DBdate($date)
    {
        $date = new Zend_Date($date,'DD/MM/YYYY');
        return $date->getIso();
    }

    /**
     * @brief Metoda pomocnicza sprawdzajca status zalogowania
     * 
     * Za jej pomocą sprawdzane jest cz uzytkownik jest zalogowany.
     * 
     */ 
    private function actionIsProtected() {
        if(empty($this->_user)) {
            $this->_helper->flashMessenger->addMessage("warning/Zaloguj się!");
            $this->_helper->redirector('login','auth');
        }
    }
}

